/***************************************************************************
 创建者: 华磊
 开始时间: 2020.8.14
 copyright: (C) 华友高科
 修改说明: (每次有修改就添加一条，带有 修改人，修改时间，修改描述)
 example (1) hualei 2020.5.8 类的具体实现代码编写

 ***************************************************************************
 *  @file x.h
 *  功能:
 *
 *                                                                         *
 ***************************************************************************/
#ifndef ECATBUSMANAGER_H
#define ECATBUSMANAGER_H

#include <QMultiMap>
#include "ecatconfig.h"
#include "ecatmotor.h"
#include "ecatio.h"
#include "domparser.h"
#include "GeneralDefine.h"

#define D_MAX_ENCODER_RECEIVER_COUNT 10
#define D_MAX_IOMODULE_COUNT 100

class RobotControl;
class RfidData;
class MaganeticSensorData;
class EncoderReceiver;

/**
 * @brief The EcatBusManager class bus的配置读取类
 */
class EcatBusManager : public  DomParser
{

public:
    EcatBusManager( RobotControl* robctl );

public:
    int getEthercatSlavesInformation(std::vector<EcatBusDevInfo_gsoap>& slavesInfo );
    int initial(int ethercatLibType, bool isUseEthercatDeivce,
                bool isUseModbusRtuDeivce, bool isUseModbusTcpDeivce, bool isUseCanopenDeivce);
    int addVirtualDevices( );

    /**
     * @brief addDevice 添加一个设备; 要按顺序添加 node: 0~n.  igh操作
     * @param devInfo
     */
    void addDevice(const EcatBusDevInfo &devInfo );

    bool isInitialOk();

    bool getXmlFilesStatus();

    int  addModbusTcpDeviceTORobotBase(int &aliasOut);

    int  addModbusRtuDeviceTORobotBase(int &aliasOut);

    int  addCanopenDeviceTORobotBase(int &aliasOut);

    //1.检查总线到机器人设备映射是否正确,2 为robotbase添加axis io_module,3 检查网线是否插错,配置文件节点号与实际节点号是否一致
    int checkRobotLogicalAxisMapEthercatAxis(int &nodeReturn, int &aliasReturn);

    int  devCount(){ return ethercatDeviceSize; }
    bool isMapOk(){ return _isMapOk; }
    bool isLinkOk(){ return isCheckAlias?_isLinkOk:true; }

    int getDeviceArryIndexByAlias_ethercatDevice(int alias,int &vectorIndexOut);
    int getDeviceArryIndexByNodeId_ethercatDevice(int nodeId,int &vectorIndexOut);
    bool getEthercatNodeIdByAlias(int alias, int&node);//ethercat根据alias, 获取ecat　node号. 没有加锁保护

    //---------------------------------------------------------------------------------
private:
    int getIndexByAlias_MotorVector(QVector<EcatMotor*> motorVector,int alias,int& indexOut);
    int getIndexByAlias_IoModuleVector(QVector<EcatIo*> ioModuleVector,int alias,int& indexOut);
//    int getModbusTcpIoPointer(int alias,EcatIo* ioModulePointer);
//    int getModbusRtuIoPointer(int alias,EcatIo* ioModulePointer);
//    int getModbusTcpMotorPointer(int alias,EcatMotor* motorPointer);
//    int getModbusRtuMotorPointer(int alias,EcatMotor* motorPointer);

    void initAliasMapNode();
    //   QMap<int,QString> robotsFolderMap;  //<机器人ID， 对应文件夹>

//#ifdef D_USE_ACONTIS
    int readCmdXml( QString xmlfile );
//#endif
    int readVirtualDeviceXml( QString xmlfile ) ;
    int readEcatBusXml( QString xmlfile ) ;
    int readModBusRtuXml( QString xmlfile );
    int readModBusTcpXml( QString xmlfile );
    int readCanopenBusXml( QString xmlfile ) ;
    int readMotorConfigXml(QString filepath,QVector<SdoConfig> &sdoConfigListOut);
    void addMsg( int messageLevel,
                 std::string componentName,
                 std::string messageType,
                 int messageCode,
                 int robotId,
                 int parameter1 = 0,
                 int parameter2 = 0,
                 int parameter3 = 0,
                 int parameter4 = 0,
                 QString message= "");



    //---------------------------------------------------------------------------------
public://对ecat主站公开

    bool isCheckAlias;
    S_EcatDevInfo ec_devInfo[D_MAX_SLAVES];//igh 添加,索引为node号. 被igh直接读写。
    /**
     * @brief nodeToRobotIdAndAxis //通过站号直接获取机器人ID和轴号 (当设备类型为io时，对应io模块)
     *  (io模块多个机器人公用时，无法处理RobotId)
     *
     */
    SRobotIdAndAxit  nodeToRobotIdAndAxis[D_MAX_SLAVES];//igh 添加,索引为node号
    int dcCycle;

#if 0
    /**
    * @brief robotDevs  //<别名,设备信息>
    */
    QMultiMap<int, S_EcatDevInfo* > aliasMapDevInfo;
#endif

//#ifdef D_USE_ACONTIS
    QString cmdLine;
    QString eniFile;
//#endif

    QVector<EcatMotor*> ec_motors;//按ethercat node id排序（虚拟的用空补充）
    QVector<EcatIo*> ec_ioModule;//按ethercat node id排序（虚拟的用空补充）
    QVector<EncoderReceiver*> encoderReceivers;//按ethercat node id排序（虚拟的用空补充）
    EncoderReceiver* encoderReceiverArry[D_MAX_ENCODER_RECEIVER_COUNT];//用于无锁使用。
    EcatIo* ec_ioModuleArry[D_MAX_IOMODULE_COUNT];//用于无锁使用。
    int ec_motorSize;
    int ec_ioModuleSize;
    int encoderReceiverSize;

    QList<QString> xmlFilelist_ethercat;//ecat 设备,按照节点号排序
    QList<int> deviceTypeList_ethercat;//ecat 设备
    QList<int> aliasList_ethercat;//ecat 设备
    QList<int> deviceChannel_ethercat;//ecat 设备


    QList<QString> xmlFilelist_canopen;//canopen 设备
    QList<int> deviceTypeList_canopen;//canopen 设备
    QList<int> aliasList_canopen;//canopen 设备
    QList<int> busIdList_canopen;//canopen 设备
    QList<int> deviceIdList_canopen;//canopen 设备
    QList<int> vendorId_canopen;//canopen 设备
    QList<int> deviceChannel_canopen;//ecat 设备

    int canopen_motorSize;//canopen
    int canopen_ioModuleSize;//canopen
    int canopen_rfidSize;//canopen
    int canopen_maganeticSize;//canopen
    int canopen_batterySize;//canopen
    int dcCycle_canopen;//canopen设备
     QVector<EcatMotor*> canopen_motors;//按ethercat node id排序（虚拟的用空补充）
     QVector<EcatIo*> canopen_ioModule;//按ethercat node id排序（虚拟的用空补充）
     QVector<RfidData*> canopen_rfidData;
     QVector<MaganeticSensorData*> canopen_maganeticData;


    //mdobus rtu,目前仅仅支持一个串口上面的所有设备
    QVector<EcatMotor*> modbus_rtu_motors;//modbus_rtu设备
    QVector<EcatIo*> modbus_rtu_ioModule;//modbus_rtu设备
    int modbus_rtu_motorSize;//modbus_rtu设备
    int modbus_rtu_ioModuleSize;//modbus_rtu设备
    int dcCycle_modbus_rtu;//modbus_rtu设备

    QList<QString> xmlFilelist_modbus_rtu;//modbusrtu设备
    QList<int> deviceTypeList_modbus_rtu;//modbusrtu设备
    QList<int> aliasList_modbus_rtu;//modbus_rtu设备

    //mdobus tcp,目前支持多个ip设备同时工作

    QVector<EcatMotor*> modbus_tcp_motors;//modbus_tcp设备
    QVector<EcatIo*> modbus_tcp_ioModule;//modbus_tcp设备
    int modbus_tcp_motorSize;//modbus_tcp设备
    int modbus_tcp_ioModuleSize;//modbus_tcp设备
    int dcCycle_modbus_tcp;//modbus_tcp设备

    QList<QString> xmlFilelist_modbus_tcp;//modbus_tcp设备
    QList<int> deviceTypeList_modbus_tcp;//modbus_tcp设备
    QList<int> aliasList_modbus_tcp;//modbus_tcp设备

    //---------------------------------------------------------------------------------

private:

    RobotControl* robCtl;
    bool isInitialOkStatus;
    int ethercatDeviceSize;
    bool _isMapOk;
    bool _isLinkOk;

    QMap<int,int> ethercat_nodeAndVectorIndex;

    bool isBusDevXmlFileReadOk;




};

#endif // ECATBUSMANAGER_H
